from flask import Flask, request, jsonify
from flask_cors import CORS
import numpy as np
import base64
import io
from PIL import Image
from models import Database
from face_recog import FaceRecognition

# 创建Flask应用
app = Flask(__name__)
# 启用CORS以允许跨域请求
CORS(app)

# 初始化数据库和人脸识别对象
db = Database()
face_recognizer = FaceRecognition()

@app.route('/api/register', methods=['POST'])
def register():
    """注册新用户的人脸"""
    try:
        # 获取请求数据
        data = request.get_json()
        name = data.get('name')
        image_base64 = data.get('image')
        
        if not name or not image_base64:
            return jsonify({'error': '缺少必要的参数'}), 400
        
        # 解码Base64图像数据
        # 移除base64前缀（如果有的话）
        if 'base64,' in image_base64:
            image_base64 = image_base64.split('base64,')[1]
        
        try:
            image_data = base64.b64decode(image_base64)
        except Exception as decode_error:
            print(f"图像解码失败: {decode_error}")
            return jsonify({'error': '图像格式无效'}), 400
        
        # 检测图像中的人脸位置
        face_locations = face_recognizer.detect_faces(image_data)
        if len(face_locations) == 0:
            return jsonify({'error': '未检测到人脸，请重新上传照片'}), 400
        elif len(face_locations) > 1:
            print(f"检测到多张人脸，数量: {len(face_locations)}")
            return jsonify({'error': '检测到多张人脸，请确保只包含一张清晰的人脸'}), 400
        
        # 直接使用二进制数据提取人脸编码
        face_encoding = face_recognizer.extract_face_encoding(image_data)
        
        if face_encoding is None:
            return jsonify({'error': '无法提取人脸特征，请确保人脸清晰可见'}), 400
        
        # 验证人脸编码的有效性
        if not isinstance(face_encoding, (list, np.ndarray)) or len(face_encoding) != 128:
            print(f"无效的人脸编码: 类型={type(face_encoding)}, 长度={len(face_encoding) if hasattr(face_encoding, '__len__') else '未知'}")
            return jsonify({'error': '人脸特征提取失败'}), 500
        
        # 在注册前，先检查是否已经存在匹配的用户
        users = db.get_all_face_encodings()
        if users:
            # 准备已知人脸编码和对应的用户信息
            known_face_encodings = [user['face_encoding'] for user in users]
            
            # 比对人脸，检查是否已注册
            is_match, match_index = face_recognizer.compare_faces(
                face_encoding, known_face_encodings
            )
            
            if is_match and match_index != -1 and 0 <= match_index < len(users):
                # 发现匹配的已注册用户
                matched_user = users[match_index]
                print(f"检测到重复注册: {matched_user['name']} (ID: {matched_user['id']})")
                return jsonify({
                    'success': False,
                    'error': '该人脸已注册',
                    'existing_user': {
                        'id': matched_user['id'],
                        'name': matched_user['name']
                    }
                }), 409  # 409 Conflict状态码表示资源冲突
        
        # 保存到数据库（add_user方法会处理格式转换）
        user_id = db.add_user(name, face_encoding)
        
        return jsonify({
            'success': True,
            'message': '注册成功',
            'user_id': user_id
        }), 201
        
    except Exception as e:
        print(f"注册失败: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/recognize', methods=['POST'])
def recognize():
    """识别人脸并返回匹配的用户信息"""
    try:
        # 获取请求数据
        data = request.get_json()
        image_base64 = data.get('image')
        
        if not image_base64:
            return jsonify({'error': '缺少图像数据'}), 400
        
        # 解码Base64图像数据
        if 'base64,' in image_base64:
            image_base64 = image_base64.split('base64,')[1]
        
        try:
            image_data = base64.b64decode(image_base64)
        except Exception as decode_error:
            print(f"图像解码失败: {decode_error}")
            return jsonify({'error': '图像格式无效'}), 400
        
        # 检测图像中的人脸位置（额外的人脸检测验证）
        face_locations = face_recognizer.detect_faces(image_data)
        if len(face_locations) == 0:
            return jsonify({'error': '未检测到人脸'}), 400
        elif len(face_locations) > 1:
            print(f"检测到多张人脸，数量: {len(face_locations)}")
            return jsonify({'error': '检测到多张人脸，请确保只包含一张清晰的人脸'}), 400
        
        # 直接使用二进制数据提取人脸编码
        face_encoding = face_recognizer.extract_face_encoding(image_data)
        
        if face_encoding is None:
            return jsonify({'error': '无法提取人脸特征，请确保人脸清晰可见'}), 400
        
        # 验证人脸编码的有效性
        if not isinstance(face_encoding, (list, np.ndarray)) or len(face_encoding) != 128:
            print(f"无效的人脸编码: 类型={type(face_encoding)}, 长度={len(face_encoding) if hasattr(face_encoding, '__len__') else '未知'}")
            return jsonify({'error': '人脸特征提取失败'}), 500
        
        # 获取所有用户的人脸编码
        users = db.get_all_face_encodings()
        
        if not users:
            return jsonify({'error': '暂无注册用户'}), 404
        
        # 准备已知人脸编码和对应的用户信息
        known_face_encodings = [user['face_encoding'] for user in users]
        
        # 比对人脸 - 添加详细日志
        print(f"开始人脸识别比对，已知用户数量: {len(known_face_encodings)}")
        print(f"提取的人脸编码类型: {type(face_encoding)}")
        
        is_match, match_index = face_recognizer.compare_faces(
            face_encoding, known_face_encodings
        )
        print(f"比对结果: 匹配={is_match}, 匹配索引={match_index}")
        
        if is_match and match_index != -1 and 0 <= match_index < len(users):
            # 更新用户最后登录时间
            matched_user = users[match_index]
            db.update_last_login(matched_user['id'])
            
            print(f"成功识别用户: {matched_user['name']} (ID: {matched_user['id']})")
            return jsonify({
                'success': True,
                'recognized': True,
                'user': {
                    'id': matched_user['id'],
                    'name': matched_user['name']
                }
            }), 200
        else:
            print("未识别到匹配的用户")
            # 返回200状态码，让前端能够正确处理未识别的情况
            return jsonify({
                'success': True,
                'recognized': False,
                'message': '未识别'
            }), 200
            
    except Exception as e:
        print(f"识别失败: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/users', methods=['GET'])
def get_users():
    """获取所有注册用户"""
    try:
        users = db.get_all_users()
        return jsonify({
            'success': True,
            'users': users
        }), 200
    except Exception as e:
        print(f"获取用户列表失败: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    """删除指定用户"""
    try:
        success = db.delete_user(user_id)
        if success:
            return jsonify({
                'success': True,
                'message': '用户删除成功'
            }), 200
        else:
            return jsonify({
                'error': '用户不存在'
            }), 404
    except Exception as e:
        print(f"删除用户失败: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/health', methods=['GET'])
def health_check():
    """健康检查端点"""
    return jsonify({
        'status': 'ok',
        'message': '人脸识别服务运行正常'
    }), 200

if __name__ == '__main__':
    # 在开发环境中运行Flask服务器
    print("人脸识别服务启动中...")
    print("健康检查: http://localhost:5000/api/health")
    app.run(host='0.0.0.0', port=5000, debug=True)